home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-07-30 | 49.0 KB | 2,382 lines |
- /*****
- * ObjDB.c
- *
- * Methods for a DataBase Object.
- {
- *****/
- #import "ObjDB.h"
- #import <objc/Storage.h>
- #import <streams/streams.h>
- #define MAXLINE 80
- #define TRUE -1
- #define FALSE !TRUE
- #define ISNEW FALSE
- #define EXISTS TRUE
- #define BIGNUM 0
- #define LASTISN 999999
-
- @implementation ObjDB
-
- - init: (char *)dbname data_use_fraction: (float)dFraction
- {
- char tmp_buffer[BUFFSIZE], name[BUFFSIZE], *space_locator;
- int i, *isns;
- [self setDescriptors];
- myDFD = [[Storage alloc] initCount:0 elementSize:sizeof(FIELD)
- description:field_desc];
- storInfo = [[Storage alloc] initCount:0 elementSize:sizeof(DBINFO)
- description:storage_desc];
- isnTable = [[Storage alloc] initCount:0 elementSize:BUFFSIZE
- description:isns_desc];
- spaceTable =[[Storage alloc] initCount:0 elementSize:BUFFSIZE
- description:space_table_desc];
- buffers = [[Storage alloc] initCount:0 elementSize:sizeof(BUFFER)
- description:buffer_desc];
- cacheCalls=0;
- cacheHits=0;
- cacheWrites=0;
- [self pushList:0];
- myInfo = (DBINFO *)malloc(sizeof(DBINFO));
- [storInfo addElement:(DBINFO *)myInfo];
- strcpy(myInfo->dBaseName, dbname);
- myInfo->data_file.blks = 1;
- myInfo->data_file.rover = 0;
- myInfo->max_isns = NUM_ISNS;
- myInfo->max_keys = 0;
- myInfo->num_keys = 0;
- myInfo->last_isn = 0;
- myInfo->data_frac = dFraction;
- myInfo->buff_size = BUFFSIZE;
- myInfo->version = VERSION;
- myInfo->nbuf = 10;
-
- if (BUFFSIZE < 256)
- {
- printf("Error: Buffer sizes less than 256 not allowed\n");
- exit(0);
- }
- if (ISNRECSIZE <= 1)
- {
- printf("Error: ISNRECSIZE <= 1\n");
- exit(0);
- }
- if (ISNRECSIZE > ISNSIZE)
- {
- printf("Error: ISNRECSIZE > ISNSIZE\n");
- exit(0);
- }
-
- /*
- i = BUFFSIZE;
- printf("%02x",i);
- put_num(tmp_buffer,&i);
- printf(" Buffersize is %d\n",(int)get_num(tmp_buffer));
-
- */
- for (i=0; i<BUFFSIZE; i++)
- tmp_buffer[i] = '\0';
-
- strcpy(name,myInfo->dBaseName);
- strcat(name,".dat");
- myInfo->data_file.ptr = fopen(name,"w");
- for (i=0;i<myInfo->data_file.blks; i++)
- fwrite(tmp_buffer, sizeof(char), BUFFSIZE, myInfo->data_file.ptr);
- fclose(myInfo->data_file.ptr);
- myInfo->data_file.ptr = fopen(name,"r+");
-
- isns = (int *)calloc(NUM_ISNS,ISNSIZE);
- space_locator = (char *)calloc(BUFFSIZE,sizeof(char));
-
- for (i=0; i<NUM_ISNS; i++)
- isns[i] = -1;
- [isnTable addElement:(int *)isns];
-
- for (i=0; i<BUFFSIZE; i++)
- space_locator[i] = '\0';
- [spaceTable addElement:(char *)space_locator];
-
- buffer = (BUFFER *)malloc(sizeof(BUFFER));
- buffer->block = -1;
- buffer->count = 0;
- buffer->update = FALSE;
-
- for (i=0;i<myInfo->nbuf;i++)
- [buffers addElement:buffer];
-
- printf("Allocated %d buffers\n",[buffers count]);
-
- free(buffer);
-
-
- free(isns);
- free(space_locator);
- return self;
- }
-
- - setDescriptors
- {
-
- sprintf(field_desc,"{i[3c]c[16c]c[12c]!!}");
- sprintf(storage_desc,"{[100c]{!ii}iiiifiiiiiiiii}");
- sprintf(isns_desc,"[%di]",NUM_ISNS);
- sprintf(space_table_desc,"[%dc]",BUFFSIZE);
- sprintf(buffer_desc,"{iii[%dc]}",BUFFSIZE);
- sprintf(hash_desc,"{[24c]ii}");
- return self;
- }
-
- - close
- {
- int i;
-
- for (i=0;i<10;i++)
- {
- buffer = [buffers elementAt:i];
- if (buffer->update == TRUE)
- {
- /*
- printf("Writing block %d\n",buffer->block);
- */
- writeRandom(buffer->data,myInfo->data_file.ptr,
- buffer->block,BUFFSIZE);
- }
- }
- [storInfo replace:(DBINFO *)myInfo at:0];
- fclose(myInfo->data_file.ptr);
- return self;
- }
-
- - free
- {
- [super free];
- return self;
- }
-
- - awake
- {
- char name[BUFFSIZE];
- int i;
-
- [super awake];
- [self setDescriptors];
- myInfo = [storInfo elementAt:0];
- if ( myInfo->buff_size != BUFFSIZE )
- {
- printf("Error: Database %s created with buffersize = %d, not %d\n",
- myInfo->dBaseName,myInfo->buff_size,BUFFSIZE);
- exit(0);
- }
- strcpy(name,myInfo->dBaseName);
- strcat(name,".dat");
- if ((myInfo->data_file.ptr = fopen(name,"r+")) == NULL)
- {
- printf("Error: No data file for DB %s\n",myInfo->dBaseName);
- exit(0);
- }
- cacheCalls=0;
- cacheHits=0;
- cacheWrites=0;
- [self pushList:0];
-
- buffers = [[Storage alloc] initCount:0 elementSize:sizeof(BUFFER) description:buffer_desc];
- buffer = (BUFFER *)malloc(sizeof(BUFFER));
- buffer->block = -1;
- buffer->count = 0;
- buffer->update = FALSE;
- for (i=0;i<myInfo->nbuf;i++)
- [buffers addElement:buffer];
- /*
- printf("Allocated %d buffers\n",[buffers count]);
- */
- free(buffer);
- /*
- printf("Buffer data addresses are:\n");
- for (i=0;i<myInfo->nbuf;i++)
- {
- buffer = [buffers elementAt:i];
- printf("%d) %02x \n",i,&buffer->data);
- }
- */
- return self;
- }
-
- - prtCacheStats
- {
- printf("--------Cache Statistics--------\n");
- printf("Calls : %d\n",cacheCalls);
- printf("Writes: %d\n",cacheWrites);
- printf("Hits: %d\n\n",cacheHits);
- return self;
- }
-
- - (int)numberFlds
- {
- return [myDFD count];
- }
-
- - addFldDesc:(FIELD *)newFldDesc
-
- {
- int *isns, i;
-
- if (newFldDesc->keyed == 'K') {
- /*
- Allocate key storage isn-lists, chain them
- Allocate heads of hash tables for this key
- */
- newFldDesc->hash = [[Storage alloc] initCount:0
- elementSize:sizeof(KEY_VALUE) description:hash_desc];
- newFldDesc->key_isns = [[Storage alloc] initCount:0
- elementSize:BUFFSIZE description:isns_desc];
-
- isns = (int *)calloc(NUM_ISNS,ISNSIZE);
- /* Initialize isns for keys */
- for (i=0; i<NUM_ISNS;i++)
- isns[i] = 0;
-
- [newFldDesc->key_isns addElement:(int *)isns];
- myInfo->num_keys++;
- [myDFD addElement:(FIELD *)newFldDesc];
- free(isns);
- }
- else
- [myDFD addElement:(FIELD *)newFldDesc];
- return self;
- }
-
- - (FIELD *) getFldDesc:(int)theFldNum
- {
- if ((theFldNum >= 0) && (theFldNum < [self numberFlds]))
- return [myDFD elementAt:theFldNum];
- else return NULL;
- }
-
- - (int)getFldNumForAbbrev:(char *)fldAbbrev
- {
- int i = [self numberFlds], j;
- FIELD *myField;
-
- for (j = 0; j<i; j++)
- {
- myField = [self getFldDesc:j];
- if ( !strcmp(myField->abbrev,fldAbbrev))
- return j;
- }
- return -1;
- }
-
- - (int)numKeyedFlds
- {
- return myInfo->num_keys;
- }
-
- - loadDFD:(FILE *)dfd_file
- {
- char name[BUFFSIZE];
- FIELD *myField = (FIELD *)malloc(sizeof(FIELD));
-
- strcpy(name,myInfo->dBaseName);
- strcat(name,".dfd");
- if((dfd_file = (FILE *)fopen(name,"r")) == NULL)
- {
- printf("Error: loadDFD...descriptor file %s not found\n",name);
- return NULL;
- }
-
- while(!feof(dfd_file))
- {
- fscanf(dfd_file,"%s %c %d %s %c %s\n",
- myField->abbrev,&(myField->kind),&(myField->display_len)
- ,myField->name,&(myField->keyed),myField->edit_mask);
- [self addFldDesc:(FIELD *)myField];
- }
- free(myField);
- close(dfd_file);
- return self;
- }
-
- - (char *)getBlk:(int) blkreq
- {
- BUFFER *myBuffer;
-
- if (blkreq < myInfo->data_file.blks)
- myBuffer = [self locBlk:blkreq];
- else myBuffer = [self newBlk:blkreq];
- return myBuffer->data;
-
- }
-
- - (BUFFER *)newBlk:(int) blkreq
- {
- BUFFER *myBuffer;
- int i;
- char *space;
-
- myBuffer = [self locBlk:blkreq];
-
- for (i=0; i<BUFFSIZE; i++)
- myBuffer->data[i] = '\0';
-
- if (blkreq/BUFFSIZE == [spaceTable count])
- {
- space = (char *)malloc(BUFFSIZE);
- for (i=0; i<BUFFSIZE; i++)
- space[i] = '\0';
- [spaceTable addElement:(char *)space];
- free(space);
- }
-
- [self allocSpace:0 in:blkreq];
- myInfo->data_file.blks++;
- return myBuffer;
- }
-
- - (BUFFER *)locBlk:(int) blkreq
- {
- int i, j, k, lowcount;
- BUFFER *myBuffer;
-
- cacheCalls++;
-
- j = [buffers count];
- for (i=0; i<j; i++)
- {
- myBuffer = [buffers elementAt:i];
- /* Adjust useage counts */
- myBuffer->count--;
- }
-
- /* See if block is already here */
- for (i=0;i<j;i++)
- {
- myBuffer = [buffers elementAt:i];
- if (myBuffer->block == blkreq)
- {
- myBuffer->count++;
- cacheHits++;
- return myBuffer;
- }
- }
-
- myBuffer = [buffers elementAt:0];
- k = 0;
- lowcount = myBuffer->count;
-
- for (i=0;i<j;i++)
- {
- myBuffer = [buffers elementAt:i];
- if (myBuffer->count < lowcount)
- {
- lowcount = myBuffer->count;
- k = i;
- }
- }
- myBuffer = [buffers elementAt:k];
- if (myBuffer->update == TRUE)
- {
- writeRandom(myBuffer->data,myInfo->data_file.ptr,
- myBuffer->block,BUFFSIZE);
- /*
- printf("Block %d written out\n",myBuffer->block);
- */
- cacheWrites++;
- }
- if (blkreq < myInfo->data_file.blks)
- readRandom(myBuffer->data,myInfo->data_file.ptr,
- blkreq,BUFFSIZE);
- myBuffer->block = blkreq;
- myBuffer->update = FALSE;
- myBuffer->count = 0;
-
- return myBuffer;
- }
-
- - write:(NXTypedStream *)typedStream
- {
- int i, num_flds;
- FIELD *myField;
-
- [super write:typedStream];
- NXWriteObject(typedStream,myDFD);
- NXWriteObject(typedStream,storInfo);
- NXWriteObject(typedStream,isnTable);
- NXWriteObject(typedStream,spaceTable);
-
- num_flds = [self numberFlds];
- for (i=0; i<num_flds; i++)
- {
- myField = [self getFldDesc:i];
- if (myField->keyed == 'K')
- {
- NXWriteObject(typedStream,myField->key_isns);
- NXWriteObject(typedStream,myField->hash);
- }
- }
- return self;
- }
-
- - read:(NXTypedStream *)typedStream
- {
- int i, num_flds;
- FIELD *myField;
-
- [super read:typedStream];
- myDFD = NXReadObject(typedStream);
- storInfo = NXReadObject(typedStream);
- isnTable = NXReadObject(typedStream);
- spaceTable = NXReadObject(typedStream);
- num_flds = [self numberFlds];
- for (i=0; i<num_flds; i++)
- {
- myField = [self getFldDesc:i];
- if (myField->keyed == 'K')
- {
- myField->key_isns = NXReadObject(typedStream);
- myField->hash = NXReadObject(typedStream);
- }
- }
- return self;
- }
-
- - (int)numberIsns
- {
- return myInfo->last_isn;
- }
-
- int
- locisn(isn,buffer)
- int isn;
- char buffer[];
- {
- int isnptr,isnlen,isnnum;
- isnptr = 0;
- while ((isnlen =
- nxtisn(&isnnum,&buffer[isnptr])) != 0) {
- if (isnnum == isn) return(isnptr);
- isnptr = isnptr + isnlen;
- }
-
- return(-1);
- }
-
- int
- nxtisn(isn,buffer)
- int *isn;
- char buffer[];
- {
- int isnlen;
-
- isnlen =(int)get_num(&buffer[0]);
- *isn = (int)get_num(&buffer[0+ISNRECSIZE]);
- return(isnlen);
- }
-
- int
- loc_eob(buffer)
- char buffer[];
- {
- int rec_len, rec_ptr;
-
- rec_ptr = 0;
- while((rec_len = (int)get_num(&buffer[rec_ptr])) != 0)
- rec_ptr = rec_ptr + rec_len;
- return(rec_ptr);
- }
-
- int
- get_num(buffer)
- char buffer[];
- {
- int i, j, *k;
- char tmp[ISNSIZE];
-
- if(ISNRECSIZE != ISNSIZE)
- for(i=0;i<ISNSIZE;i++)
- tmp[i] = '\0';
-
- for(i=0;i<ISNRECSIZE;i++)
- {
- j = ISNSIZE - ISNRECSIZE + i;
- tmp[j] = buffer[i]; ;
- }
- k = &tmp[0];
- return(*k);
- }
-
- void
- put_num(buffer,val)
- char buffer[];
- char val[];
- {
- int i, j, k, *l;
-
- for(i=0;i<ISNRECSIZE;i++)
- {
- k = ISNSIZE - i - 1;
- j = ISNRECSIZE - i - 1;
- buffer[j] =val[k];
- }
- if(ISNRECSIZE < ISNSIZE)
- for(i=ISNRECSIZE;i<ISNSIZE;i++)
- if(val[ISNSIZE-i-1] != '\0')
- {
- l = &val[0];
- printf("\nError: put_num...value %d would be truncated\n",*l);
- printf(" ISNRECSIZE is too small\n");
- exit(0);
- }
- return;
- }
-
- int
- pn_N_fld(recordptr) /* Store a null field */
- char recordptr[];
- {
- recordptr[0] = 0x01;
- recordptr[1] = '\0';
- return(1);
- }
-
- int
- pn_I_fld(j,recordptr)
- char recordptr[], j[];
- {
- int i;
- int val;
- if( sizeof(i) == 2)
- recordptr[0] = 0x03;
- else recordptr[0] = 0x05;
- val=0;
- for (i=0; i < sizeof(i); i++) {
- recordptr[i+1] = j[i];
- val = val + j[i];
- }
- if( val == 0) {
- recordptr[0] = 0x01;
- recordptr[1] = '\0';
- return(1);
- }
-
- /* signals last field */
- recordptr[sizeof(i)+1] = '\0';
- return(sizeof(i)+1);
- }
- int
- pn_L_fld(j,recordptr)
- char recordptr[], j[];
- {
- int i;
- long m;
- int val;
- if( sizeof(m) == 2)
- recordptr[0] = 0x03;
- else recordptr[0] = 0x05;
- val=0;
- for (i=0; i < sizeof(m); i++) {
- recordptr[i+1] = j[i];
- val = val + j[i];
- }
- if( val == 0) {
- recordptr[0] = 0x01;
- recordptr[1] = '\0';
- return(1);
- }
-
- recordptr[sizeof(m)+1] = '\0';
- return(sizeof(m)+1);
- }
- int
- pn_A_fld(j,recordptr,recordlen)
- char recordptr[], j[];
- int recordlen;
- {
- int len, i;
-
- /* This should trim off trailing blanks */
- if ( (len = strlen(j)) > 0 ) {
- while(j[len] == ' ' )
- if ( --len == 0 ) break;
- }
- /* get length of input string */
- len = min(++len,recordlen);
- /* length will not include terminal 0 */
- recordptr[0]=len+1;
- for (i=0;i<len;i++) recordptr[i+1] = j[i];
- /* store (semi-)permanent end of record there */
- recordptr[len+1] = '\0';
- return(len+1);
- }
-
- - (int)allocSpace: (int)space in:(int) block_allocated
- {
- int charno, i, comp_fact;
- int block;
- char *mybuffer;
-
- /* byte which represents amount of space used
- depends upon Buffer Size ( 0xFF = 256)
- */
- comp_fact = BUFFSIZE/256;
- if (space > BUFFSIZE)
- {
- printf("Error: allocSpace...space %d not available\n",space);
- exit(0);
- }
-
- /* mark space used */
-
- charno = block_allocated;
- block = charno/BUFFSIZE;
- charno = mod(charno,BUFFSIZE);
- mybuffer = (char *)[spaceTable elementAt:block];
- /* get space used in block */
- i = (mybuffer[charno] & 0xFF) * comp_fact ;
- i = i + space ;
- if (i < 0 ) {
- printf("Error: allocSpace...deallocation resulted in < 0\n");
- exit(0);
- }
- if (i > BUFFSIZE) {
- printf("Error: allocSpace...requested allocation not possible\n");
- exit(0);
- }
- /* space is divided by comp_fact when stored */
- i = ( i + (comp_fact - 1))/comp_fact;
- mybuffer[charno] =( i & 0xFF);
- /* Return amount of buffer space used */
- myInfo->data_file.rover = block_allocated;
- return((int)i*comp_fact);
-
- }
-
- - (int)findSpace: (int)space :(float)data_frac
- {
- int rover, charno, i, comp_fact;
- int old_rover, old_block, block;
- char *mybuffer;
-
- /* byte which represents amount of space used
- depends upon Buffer Size ( 0xFF = 256)
- */
- comp_fact = BUFFSIZE/256;
- if (space > BUFFSIZE)
- {
- printf("Error: findSpace...space %d not available\n",space);
- exit(0);
- }
-
- /* Find a block big enough to contain a record of length "space" */
- rover = myInfo->data_file.rover;
- old_rover = rover;
- old_block = -1;
- i = 0;
-
- while(TRUE) {
- charno = rover;
- block = charno/BUFFSIZE;
- charno = mod(charno,BUFFSIZE);
- if ( block != old_block )
- {
- mybuffer = (char *)[spaceTable elementAt:block];
- old_block = block;
- }
- i = (mybuffer[charno] & 0xFF) ;
- /* space is divided by comp_fact when stored in space avail list */
- i = i * comp_fact;
- if (max(2*ISNSIZE+1,space) + i < BUFFSIZE * data_frac )
- return((int)rover); /* space + used space is adequate */
- rover = mod((myInfo->data_file.rover)++,myInfo->data_file.blks);
- if (rover == old_rover)
- return(-1L);
- }
- }
-
- - updBuf:(int)block
- {
- BUFFER *myBuffer;
-
- myBuffer = [self locBlk:block];
- myBuffer->update = TRUE;
- return self;
- }
-
- - addKey:(char *)value isnNo:(int)isn field:(FIELD *)myField
- {
- KEY_VALUE *keys;
- KEY_VALUE *fnd_keys;
- int i, j, blk, next, old_blk, *isns;
-
- if ((i =[self findKey:value field:myField]) != -1)
- {
- fnd_keys = [myField->hash elementAt:i];
- fnd_keys->count++;
- if (isn < fnd_keys->first_isn)
- {
- blk = isn/(NUM_ISNS);
- j = mod(isn,(NUM_ISNS));
- isns = [myField->key_isns elementAt:blk];
- isns[j] = fnd_keys->first_isn;
- fnd_keys->first_isn = isn;
- }
- else
- {
- next = fnd_keys->first_isn;
- old_blk = -1;
- while ( next < isn )
- {
- blk = next/(NUM_ISNS);
- j = mod(next, (NUM_ISNS));
- if (blk != old_blk)
- {
- isns = [myField->key_isns elementAt:blk];
- old_blk = blk;
- }
- if((next = isns[j]) == 0)
- {
- isns[j] = isn;
- return self;
- }
- }
- isns[j] = isn;
- blk = isn/(NUM_ISNS);
- j = mod(isn,(NUM_ISNS));
- isns = [myField->key_isns elementAt:blk];
- isns[j] = next;
- }
- return self;
- }
- keys = (KEY_VALUE *)malloc(sizeof(KEY_VALUE));
- strcpy(keys->key_value,value);
- keys->count = 1;
- keys->first_isn = isn;
- [myField->hash addElement:(KEY_VALUE *)keys];
- free(keys);
- return self;
- }
-
- - (int)findKey:(char *)value field:(FIELD *)myField
- {
- KEY_VALUE *keys;
- int j, i;
-
- j = [myField->hash count];
- for (i=0; i<j; i++)
- {
- keys = [myField->hash elementAt:i];
- if (!strcmp(keys->key_value,value))
- return i;
- }
- return -1;
- }
-
- - deleteKey:(char *)value isnNo:(int)isn field:(FIELD *)myField
- {
- KEY_VALUE *fnd_keys;
- int i, j, *isns, blk, old_blk, prev, current, next;
-
- if ((i =[self findKey:value field:myField]) != -1)
- {
- fnd_keys = [myField->hash elementAt:i];
- fnd_keys->count--;
- if (fnd_keys->count == 0)
- {
- [myField->hash removeAt:i];
- return self;
- }
- if (isn == fnd_keys->first_isn)
- {
- blk = fnd_keys->first_isn/(NUM_ISNS);
- j = mod(fnd_keys->first_isn,(NUM_ISNS));
- isns = [myField->key_isns elementAt:blk];
- fnd_keys->first_isn = isns[j];
- isns[j] = 0;
- return self;
- }
- prev = fnd_keys->first_isn;
- current = prev;
- next = current;
- old_blk = -1;
- while (next <= isn)
- {
- blk = next/(NUM_ISNS);
- j = mod(next,(NUM_ISNS));
- if (blk != old_blk)
- {
- isns = [myField->key_isns elementAt:blk];
- old_blk = blk;
- }
- prev = current;
- current = next;
- next = isns[j];
- if (next == 0) break;
- }
- blk = prev/(NUM_ISNS);
- j = mod(prev,(NUM_ISNS));
- isns = [myField->key_isns elementAt:blk];
- isns[j] = next;
- blk = current/(NUM_ISNS);
- j = mod(current,(NUM_ISNS));
- isns = [myField->key_isns elementAt:blk];
- isns[j] = 0;
- return self;
- }
- printf("Warning: deleteKey...Key %s not found\n",value);
- return self;
- }
-
- - setKeyField:(char *)abbrev
- {
- int i;
- FIELD *myField;
- int *isns;
-
- if ((myField =
- [self getFldDesc:[self getFldNumForAbbrev:abbrev]]) == NULL)
- {
- printf("Field %s not in data base\n",abbrev);
- return self;
- }
-
- if (myField->keyed == 'K')
- {
- return self;
- }
- myField->hash = [[Storage alloc] initCount:0 elementSize:sizeof(KEY_VALUE) description:hash_desc];
- myField->key_isns = [[Storage alloc] initCount:0 elementSize:BUFFSIZE description:isns_desc];
- myField->keyed = 'K';
- isns = (int *)calloc(NUM_ISNS, ISNSIZE);
- /* initialize space for key isns */
- for (i=0; i<NUM_ISNS; i++)
- isns[i] = 0;
-
- for (i=0; i<myInfo->max_isns/(NUM_ISNS);i++)
- [myField->key_isns addElement:(int *)isns];
-
- free(isns);
- myInfo->num_keys++;
- [self keyFld:abbrev];
- return self;
- }
-
- - unKeyField:(int)fldNum
- {
- FIELD *myField;
-
- if ((myField =
- [self getFldDesc:fldNum]) == NULL)
- {
- printf("Field %d not in data base\n",fldNum);
- return self;
- }
-
- if (myField->keyed != 'K')
- return self;
- printf("Freeing keys for %s\n",myField->abbrev);
- [myField->hash free];
- [myField->key_isns free];
- myField->keyed = 'N';
- [myDFD replace:(FIELD *)myField at:fldNum];
- myInfo->num_keys--;
- [storInfo replace:(DBINFO *)myInfo at:0];
- return self;
- }
-
- - unKeyDB
- {
- int i, nfields;
-
- if([self numKeyedFlds] == 0)
- {
- printf("Database not keyed\n");
- return self;
- }
- nfields = [self numberFlds];
-
- for (i=0; i<nfields; i++)
- [self unKeyField:i];
- return self;
- }
-
- - keyDB
- {
- int i,j;
-
- if([self numKeyedFlds] > 0)
- {
- printf("Database already keyed\n");
- return self;
- }
- j = [self numberIsns];
- for(i=0; i<j; i++)
- [self keyRecord:i];
- return self;
- }
-
- - prtKeyTableFor:(char *)abbrev
- {
- FIELD *myField;
- int i, k, *fnd_isns;
-
- if ((myField =
- [self getFldDesc:[self getFldNumForAbbrev:abbrev]]) == NULL)
- {
- printf("Field %s not in data base\n",abbrev);
- return self;
- }
-
- if (myField->keyed != 'K')
- {
- printf("Field Not keyed\n");
- return self;
- }
-
- fnd_isns = [myField->key_isns elementAt:0];
- printf("Data for field %s \n",abbrev);
- printf("----------Dump of first block----------\n");
- for (k=0;k<10;k++)
- {
- printf("%d ) ",k*10);
- for (i=0;i<10;i++)
- printf("%6d ",fnd_isns[i+k*10]);
- printf("\n");
- }
- return self;
- }
-
- - (int *)newList:(int)size
- {
- int *tmp;
-
- tmp = (int *)calloc(size+2,ISNSIZE);
- *tmp = size;
- tmp[size+1] = LASTISN;
- return tmp;
- }
-
- - (int *)pushList:(int)size
- {
- if(Hold) free(Hold);
- if(Last) Hold = Last;
- else Hold = [self newList:0];
- if(Isns) Last = Isns;
- else Last = [self newList:0];
- Isns = [self newList:size];
- return Isns;
- }
-
- - (int *)getIsnListforField:(char *)abbrev value:(char *)value
- {
- KEY_VALUE *keys;
- int j, i, k, *fnd_isns, blk, old_blk, count, next;
- FIELD *myField;
-
- if (!strcmp(abbrev,"*"))
- if(!strcasecmp(value,"ALL"))
- {
- Isns = [self pushList:myInfo->last_isn];
- k = 1;
- for (i=0; i<myInfo->last_isn; i++)
- if([self getBlockwithIsn:i] != -1)
- Isns[k++] = i;
- Isns[k] = LASTISN;
- *Isns = k - 1;
- return Isns;
- }
-
- if ((myField =
- [self getFldDesc:[self getFldNumForAbbrev:abbrev]]) == NULL)
- {
- printf("Field %s not in data base\n",abbrev);
- return [self pushList:0];
- }
-
- if (myField->keyed != 'K')
- {
- printf("Field Not keyed\n");
- return [self pushList:0];
- }
-
- if((j = [self findKey:value field:myField]) != -1)
- {
- keys = [myField->hash elementAt:j];
- count = keys->count;
- old_blk = -1;
- Isns = [self pushList:count];
- next = keys->first_isn;
- i = 0;
- while(1)
- {
- Isns[i+1] = next;
- i++; /* i points to location just stored into */
- blk = next/(NUM_ISNS);
- k = mod(next,(NUM_ISNS));
- if (blk != old_blk)
- {
- fnd_isns = [myField->key_isns elementAt:blk];
- old_blk = blk;
- }
- next = fnd_isns[k];
- if (next == 0) break;
- }
- Isns[0] = count;
- Isns[i+1] = LASTISN;
- if(count != i)
- printf("Warning: getIsnListforField...count=%d, #found = %d\n",
- count,i);
- return Isns;
- }
- return [self pushList:0];
- }
-
- - (int *)getIsnListforField:(char *)abbrev value:(char *)value operator:(char *)oper;
- {
- FIELD *myField;
- int i, j, *new, *isns;
- char source[BUFFSIZE], field[256];
-
- if ((myField =
- [self getFldDesc:[self getFldNumForAbbrev:abbrev]]) == NULL)
- {
- printf("Field %s not in data base\n",abbrev);
- return [self pushList:0];
- }
-
- switch(oper[0]) {
- case '=':
- case '^':
- break;
- default:
- printf("Operator %s not implemented for search\n",oper);
- return [self pushList:0];
- }
-
- Isns = [self pushList:*Isns];
- new = Isns;
- *new = 0;
- isns = Last;
-
- ++isns; ++new;
-
- strcpy(field,abbrev);
- strcat(field,",128,");
-
- switch(oper[0]) {
- case '=': /* string equality */
- for (i=0;i<*Last;i++) {
- [self getData:source atIsn:*isns describedBy: field];
- if(!strcmp(source,value)) {
- *new = *isns;
- (*Isns)++;
- new++;
- }
- isns++;
- }
- *new = LASTISN;
- break;
- case '^': /* string contains */
- for (i=0;i<*Last;i++) {
- [self getData:source atIsn:*isns describedBy: field];
- for (j=0;j<=strlen(source)-strlen(value);j++) {
- if(!strncmp(&source[j],value,strlen(value))) {
- *new = *isns;
- (*Isns)++;
- new++;
- break;
- }
- }
- isns++;
- }
- *new = LASTISN;
- break;
- }
- return Isns;
- }
-
- - listKeysForField:(char *)abbrev
- {
- KEY_VALUE *keys;
- int j, i;
- FIELD *myField;
-
- if ((myField =
- [self getFldDesc:[self getFldNumForAbbrev:abbrev]]) == NULL)
- {
- printf("Field %s not in data base\n",abbrev);
- return self;
- }
-
- if (myField->keyed != 'K')
- {
- printf("Field Not keyed\n");
- return self;
- }
- j = [myField->hash count];
- for (i=0; i<j; i++)
- {
- keys = [myField->hash elementAt:i];
- printf("%d) %s - %d -> %d\n",
- i,keys->key_value,keys->count,keys->first_isn);
- }
- return self;
- }
-
- - (int) addData:(char *)source:(char *)descript
- {
- int i, j, blk_alloc, use_isn;
-
- i = get_reclen(descript);
- if((blk_alloc =
- [self findSpace:i :myInfo->data_frac]) == -1L)
- {
- [self getBlk:myInfo->data_file.blks];
- if((blk_alloc =
- [self findSpace:i :myInfo->data_frac]) == -1L)
- {
- printf("Error: addData...Unable to allocate new space\n");
- exit(0);
- }
- /*
- printf("Allocated new data block %d\n",blk_alloc);
- */
- }
- use_isn = [self geta_isn];
- j = [self addrec:blk_alloc:use_isn:source:descript];
- [self setIsn:use_isn ToBlock:blk_alloc];
- [self updBuf:blk_alloc];
- [self allocSpace:j in:blk_alloc];
- if([self numKeyedFlds] > 0)
- [self keyRecord:use_isn];
- return use_isn;
- }
-
- - (fld_index *)bldFldIndex:(char *)descript
- {
- static char old_descript[BUFFSIZE] = "";
- static int *myfld;
- static int *myofset;
- static int l;
- int i,j,k, fldnum, fldlen;
- char fld_name[3];
- static fld_index *myIndex;
-
- if (strcmp(old_descript,descript) != 0) {
- strcpy(old_descript,descript);
-
- l = [self numberFlds];
- if(strcmp(old_descript,""))
- {
- myfld = (int *)calloc(l,sizeof(int));
- myofset = (int *)calloc(l,sizeof(int));
- myIndex = (fld_index *)malloc(sizeof(fld_index));
- }
- for (i=0; i<l;i++) {
- myfld[i] = 0;
- myofset[i] = 0;
- }
- i = 0;
- j = 0;
- l = 0;
- k = 0;
- while(i < strlen(descript)) {
- j = get2(&descript[i],&fld_name,&fldlen);
- i = i + j;
- if ((fldnum = [self getFldNumForAbbrev:fld_name]) == -1 )
- {
- printf("Error: addrec...bad field %s in descript\n",fld_name);
- exit(0);
- }
- l = max(l,fldnum);
- myfld[fldnum] = fldlen;
- myofset[fldnum] = k;
- k = k + fldlen;
- }
-
- myIndex->fld = myfld;
- myIndex->ofset = myofset;
- myIndex->l = l + 1;
- }
- return myIndex;
-
- }
-
- - keyRecord:(int)isn
- {
- char *mybuffer;
- char num_str[BUFFSIZE];
- int j, k, nfields, blk;
- FIELD *myField;
-
- /* key data for record in isn */
- if ((blk = [self getBlockwithIsn:isn]) == -1)
- return NULL;
- mybuffer = (char *)[self getBlk:blk];
- j = locisn(isn,&mybuffer[0]);
- nfields = [self numberFlds];
- for (k = 0; k < nfields; k++) {
- myField = [self getFldDesc:k];
- if ( myField->keyed == 'K' )
- switch (myField->kind) {
- case 'I':
- if(gn_I_fld(num_str,k,&mybuffer[j]) != 0)
- [self addKey:num_str isnNo:isn field:myField];
- else [self addKey:"0" isnNo:isn field:myField];
- break;
- case 'L':
- if(gn_L_fld(num_str,k,&mybuffer[j]) != 0)
- [self addKey:num_str isnNo:isn field:myField];
- else [self addKey:"0" isnNo:isn field:myField];
- break;
- case 'A':
- if(gn_A_fld(num_str,k,BUFFSIZE,&mybuffer[j]) != 0)
- [self addKey:num_str isnNo:isn field:myField];
- else [self addKey:"" isnNo:isn field:myField];
- break;
- }
-
- }
- return self;
- }
-
- - deKeyRecord:(int)isn
- {
- char *mybuffer;
- char num_str[BUFFSIZE];
- int j, k, nfields, blk;
- FIELD *myField;
-
- /* de-key data for record in isn */
- if((blk = [self getBlockwithIsn:isn]) == -1)
- return NULL;
- mybuffer = (char *)[self getBlk:blk];
- j = locisn(isn,&mybuffer[0]);
- nfields = [self numberFlds];
- for (k = 0; k < nfields; k++) {
- myField = [self getFldDesc:k];
- if ( myField->keyed == 'K' )
- switch (myField->kind) {
- case 'I':
- if(gn_I_fld(num_str,k,&mybuffer[j]) != 0)
- [self deleteKey:num_str isnNo:isn field:myField];
- else [self deleteKey:"0" isnNo:isn field:myField];
- break;
- case 'L':
- if(gn_L_fld(num_str,k,&mybuffer[j]) != 0)
- [self deleteKey:num_str isnNo:isn field:myField];
- else [self deleteKey:"0" isnNo:isn field:myField];
- break;
- case 'A':
- if(gn_A_fld(num_str,k,BUFFSIZE,&mybuffer[j]) != 0)
- [self deleteKey:num_str isnNo:isn field:myField];
- else [self deleteKey:"" isnNo:isn field:myField];
- break;
- }
-
- }
- return self;
- }
-
- - keyFld:(char *)abbrev
- {
- int fldNum, i, j;
-
- if((fldNum = [self getFldNumForAbbrev:abbrev]) == -1)
- {
- printf("Error: keyFld...field %s not defined\n",abbrev);
- exit(0);
- }
-
- j = [self numberIsns];
- for (i=0; i<j; i++)
- [self keyFld:fldNum forIsnNum:i];
- return self;
- }
-
- - keyFld:(int)fldNum forIsnNum:(int)isn
- {
- char *mybuffer;
- char num_str[BUFFSIZE];
- int j, k, nfields, blk;
- FIELD *myField;
-
- /* key data for record in isn */
- if ((blk = [self getBlockwithIsn:isn]) == -1)
- return NULL;
- mybuffer = (char *)[self getBlk:blk];
- j = locisn(isn,&mybuffer[0]);
- nfields = [self numberFlds];
- k = fldNum;
- myField = [self getFldDesc:k];
- if ( myField->keyed == 'K' )
- switch (myField->kind) {
- case 'I':
- if(gn_I_fld(num_str,k,&mybuffer[j]) != 0)
- [self addKey:num_str isnNo:isn field:myField];
- else [self addKey:"0" isnNo:isn field:myField];
- break;
- case 'L':
- if(gn_L_fld(num_str,k,&mybuffer[j]) != 0)
- [self addKey:num_str isnNo:isn field:myField];
- else [self addKey:"0" isnNo:isn field:myField];
- break;
- case 'A':
- if(gn_A_fld(num_str,k,BUFFSIZE,&mybuffer[j]) != 0)
- [self addKey:num_str isnNo:isn field:myField];
- else [self addKey:"" isnNo:isn field:myField];
- break;
- }
- return self;
- }
-
- - (int)addrec:(int)blkno:(int)isn:(char *)source:(char *)descript
- {
- char *mybuffer;
- FIELD *myField;
- int hold,i,j, k, l, zero;
- fld_index *myFlds;
-
- myFlds = [self bldFldIndex:descript];
- zero = 0;
- l = [self numberFlds];
- i = 0;
- mybuffer = (char *)[self getBlk:blkno];
- i = loc_eob(&mybuffer[0]);
- hold = i;
- put_num(&mybuffer[i+ISNRECSIZE],&isn);
- /* point past rec len and isn num */
- i = i + ISNRECSIZE + ISNRECSIZE;
- /* reclen is stored in first ISNRECSIZE bytes */
- /* isn is stored in next ISNRECSIZE bytes */
- j = i;
-
- for (k = 0; k <l; k++) {
- myField = [self getFldDesc:k];
- if (myFlds->fld[k] == 0)
- {
- i = pn_N_fld(&mybuffer[j]);
- j = i+j;
- }
- else switch (myField->kind) {
- case 'I':
- i = pn_I_fld(&source[myFlds->ofset[k]],&mybuffer[j]);
- j=i+j;
- break;
- case 'L':
- i = pn_L_fld(&source[myFlds->ofset[k]],&mybuffer[j]);
- j=i+j;
- break;
- case 'A':
- i = pn_A_fld(&source[myFlds->ofset[k]],
- &mybuffer[j],myFlds->fld[k]);
- j=i+j;
- break;
- }
-
- }
- /* store record len */
- k = j - hold;
- put_num(&mybuffer[hold+0],&k);
- /* return record len */
- return(k);
- }
-
- - getData:(char *)source atIsn:(int)isn describedBy:(char *)descript
- {
- char *mybuffer;
- FIELD *myField;
- int blkno;
- int i,j, k, zero;
- fld_index *myFlds;
-
- if ((blkno = [self getBlockwithIsn:isn]) == -1)
- return NULL;
-
- myFlds = [self bldFldIndex:descript];
- zero = 0;
- i = 0;
- mybuffer = (char *)[self getBlk:blkno];
- j = locisn(isn,&mybuffer[0]);
- for (k = 0; k < myFlds->l; k++) {
- myField = [self getFldDesc:k];
- if (myFlds->fld[k] != 0)
- switch (myField->kind) {
- case 'I':
- gn_I_fld(&source[myFlds->ofset[k]],k,&mybuffer[j]);
- break;
- case 'L':
- gn_L_fld(&source[myFlds->ofset[k]],k,&mybuffer[j]);
- break;
- case 'A':
- gn_A_fld(&source[myFlds->ofset[k]],
- k,myFlds->fld[k],&mybuffer[j]);
- break;
- }
-
- }
- return self;
- }
-
- - (int)updateDataAtIsn:(int)isn with:(char *)data
- describedBy:(char *)description
- {
- int i, j, k, space_used, blk_alloc, use_isn;
- char tmp_buffer[BUFFSIZE];
-
- if((j = [self getBlockwithIsn:(int)isn]) == -1) return -1;
- k = - [self delrec:j:isn:tmp_buffer];
- [self updBuf:j];
- space_used = [self allocSpace:k in:j];
- i = get_reclen(description) - k;
- if((blk_alloc = [self findSpace:i :(float)0.99]) == -1L)
- {
- [self getBlk:myInfo->data_file.blks];
- if((blk_alloc = [self findSpace:i :(float)0.99]) == -1L)
- {
- printf("Error: updateDataAtIsn...Unable to allocate new space\n");
- exit(0);
- }
- }
- use_isn = isn;
- j = [self updrec:blk_alloc:use_isn:data:description:tmp_buffer];
- [self setIsn:use_isn ToBlock:blk_alloc];
- [self updBuf:blk_alloc];
- space_used = [self allocSpace:j in:blk_alloc];
- return use_isn;
- }
-
- - (int)updrec:(int)blkno:(int)isn:(char *)source:(char *)
- descript:(char *)old_buffer
- {
- char *mybuffer;
- char num_str[BUFFSIZE];
- FIELD *myField;
- int hold,i,j, k, zero;
- fld_index *myFlds;
-
- int nfields = [self numberFlds], mm;
-
- myFlds = [self bldFldIndex:descript];
- zero = 0;
-
- i = 0;
- mybuffer = (char *)[self getBlk:blkno];
-
- /* get place to put updated record */
- i = loc_eob(&mybuffer[0]);
- hold = i;
- put_num(&mybuffer[i+ISNRECSIZE],&isn);
- /* point past rec len and isn num */
- i = i + ISNRECSIZE + ISNRECSIZE;
- /* reclen is stored in first ISNRECSIZE bytes */
- /* isn is stored in next ISNRECSIZE bytes */
- j = i;
- for (k = 0; k < nfields; k++) {
- myField = [self getFldDesc:k];
- if (myFlds->fld[k] == 0)
- if (( mm = loc_fld(k,&old_buffer[0])) != -1) {
- i = old_buffer[mm];
- memcpy(&mybuffer[j],&old_buffer[mm],i);
- j = i+j;
- }
- else {
- i = pn_N_fld(&mybuffer[j]);
- j=i+j;
- }
- else switch (myField->kind) {
- case 'I':
- i = pn_I_fld(&source[myFlds->ofset[k]],
- &mybuffer[j]);
- j=i+j;
- if(myField->keyed == 'K')
- {
- if((gn_I_fld(num_str, k, &old_buffer[0])) != 0)
- [self deleteKey:num_str isnNo:isn field:myField];
- else [self deleteKey:"0" isnNo:isn field:myField];
- if(gn_I_fld(num_str,k,&mybuffer[hold]) != 0)
- [self addKey:num_str isnNo:isn field:myField];
- else [self addKey:"0" isnNo:isn field:myField];
- }
- break;
- case 'L':
- i = pn_L_fld(&source[myFlds->ofset[k]],
- &mybuffer[j]);
- j=i+j;
- if(myField->keyed == 'K')
- {
- if((gn_L_fld(num_str, k, &old_buffer[0])) != 0)
- [self deleteKey:num_str isnNo:isn field:myField];
- else [self deleteKey:"0" isnNo:isn field:myField];
- if(gn_L_fld(num_str,k,&mybuffer[hold]) != 0)
- [self addKey:num_str isnNo:isn field:myField];
- else [self addKey:"0" isnNo:isn field:myField];
- }
- break;
- case 'A':
- i = pn_A_fld(&source[myFlds->ofset[k]],
- &mybuffer[j],myFlds->fld[k]);
- j=i+j;
- if(myField->keyed == 'K')
- {
- if((gn_A_fld(num_str, k, BUFFSIZE, &old_buffer[0])) != 0)
- [self deleteKey:num_str isnNo:isn field:myField];
- else [self deleteKey:"" isnNo:isn field:myField];
- if(gn_A_fld(num_str,k,BUFFSIZE, &mybuffer[hold]) != 0)
- [self addKey:num_str isnNo:isn field:myField];
- else [self addKey:"" isnNo:isn field:myField];
- }
- break;
- }
-
- }
- /* store record len */
- k = j - hold;
- put_num(&mybuffer[hold+0],&k);
- /* return record len */
- return(k);
- }
-
-
- - deleteDataAtIsn:(int)isn
- {
- int j, k, space_used;
- char tmp_buffer[BUFFSIZE];
-
- if((j = [self getBlockwithIsn:(int)isn]) == -1) return NULL;
- [self deKeyRecord:isn];
- k = - [self delrec:j:isn:tmp_buffer];
- [self setIsn:isn ToBlock:-1L];
- [self updBuf:j];
- space_used = [self allocSpace:k in:j];
- return self;
- }
-
- -(int)delrec:(int)block:(int)isn:(char *)tmp_buffer
- {
- char *buff_ptr;
- int i,j,k,isnlen, nxt_isn,len_of_remainder;
- /*
- FIELD *myField;
- */
- i = 0;
- j = 0;
-
- buff_ptr= (char *)[self getBlk:block];
- if ((j = locisn(isn,&buff_ptr[0]) ) == -1)
- {
- printf("Error: delrec...isn %d not located\n",isn);
- }
- isnlen = (int)get_num(&buff_ptr[j]);
-
- for (i=0;i<=isnlen;i++)
- tmp_buffer[i] = buff_ptr[j+i];
-
- /* points to next record or eob */
- nxt_isn = j + isnlen;
- /* points to eob */
- len_of_remainder = loc_eob(&buff_ptr[j]);
-
- k = nxt_isn;
-
- for(i=0;i<len_of_remainder;i++)
- buff_ptr[j++] = buff_ptr[k++];
- k = 0;
-
- put_num(&buff_ptr[j],&k);
-
- return(isnlen);
- }
-
- int
- readRandom(p,fptr,blknum,blksize)
- int blksize;
- int blknum;
- char *p;
- FILE *fptr;
- {
- long offset, curloc;
-
- if((curloc = ftell(fptr)) == -1L) {
- printf("Error: readRandom...ftell error at block %ld\n", blknum);
- exit(0);
- }
- offset = blknum * blksize - curloc;
- if(fseek(fptr, offset, 1) != 0) {
- printf("Error: readRandom...fseek error at block %ld\n", blknum);
- exit(0);
- }
- fread(p, blksize, 1, fptr);
- if (ferror(fptr) != 0) {
- printf("Error: readRandom...read error at block %ld\n", blknum);
- exit(0);
- }
- return(TRUE);
- }
-
- int
- writeRandom(p,fptr,blknum,blksize)
- int blksize;
- int blknum;
- char *p;
- FILE *fptr;
- {
- long offset, curloc;
-
- if((curloc = ftell(fptr)) == -1L) {
- printf("Error: writeRandom...ftell error at block %ld\n", blknum);
- exit(0);
- }
- offset = blknum * blksize - curloc;
- if(fseek(fptr, offset, 1) != 0) {
- printf("Error: writeRandom...fseek error at block %ld\n", blknum);
- exit(0);
- }
- fwrite(p, blksize, 1, fptr);
- if (ferror(fptr) != 0) {
- printf("Error: writeRandom...fwrite error at block %ld\n", blknum);
- exit(0);
- }
- return(TRUE);
- }
-
- - (int)getBlockwithIsn:(int)isn
- {
- int k, block;
- int j;
- int *isns;
-
- if ( isn < 0 )
- {
- printf("Error: getisn...isn < 0\n");
- return(-1);
- }
- if (isn >= myInfo->last_isn )
- {
- printf("Error: getisn...isn > last_isn\n");
- return(-1);
- }
-
- j = isn/(NUM_ISNS);
- /* get offset into isn_block */
- k = (isn - j * (NUM_ISNS));
-
- isns = [isnTable elementAt:j];
- block = isns[k];
- return(block- 1);
- /* block is stored +1 to allow 0 to mean no block for that isn */
- }
-
- - setIsn:(int)isn ToBlock:(int)block
- {
- int k;
- int j;
- int *isns;
-
- if ( isn < 0 )
- {
- printf("Error: setisn...isn < 0\n");
- exit(0);
- }
- if (isn > myInfo->max_isns )
- {
- printf("Error: setisn...isn > max_isns\n");
- exit(0);
- }
-
- j = isn/(NUM_ISNS);
- /* get offset into isn_block */
- k = (isn - j * (NUM_ISNS));
-
- isns =[isnTable elementAt:j];
- /* block is stored +1 to allow 0 to mean no block for that isn */
- isns[k] = block + 1;
- return self;
- }
-
- - (int)geta_isn
- {
- int i;
- /* 0 is stored to mean empty.. getisn subs 1 to allow
- access to block 0 , i.e. block 0 is stored as 1
- */
- for (i=0;i<myInfo->last_isn;i++)
- if ([self getBlockwithIsn:i] == -1) return(i);
- i = myInfo->last_isn;
- if (myInfo->last_isn == myInfo->max_isns)
- [self newIsnBlock];
- myInfo->last_isn++;
- return(i);
- }
-
- - newIsnBlock
- {
- int *isns = (int *)calloc(NUM_ISNS,ISNSIZE);
- int *newisns = (int *)calloc(NUM_ISNS,ISNSIZE);
- int i,j,k, old_max;
- FIELD *myField;
- /*
- KEY_VALUE *myKeys;
- int *key_isns;
- */
-
- old_max = myInfo->max_isns;
- for (i=0; i< NUM_ISNS; i++)
- isns[i] = -1;
-
- /*
- printf("***Adding isn Table element ***\n");
- */
- [isnTable addElement:(int *)isns];
- myInfo->max_isns = myInfo->max_isns + NUM_ISNS;
-
- j = [self numberFlds];
- for (k=0;k<j;k++)
- {
- myField = [self getFldDesc:k];
- /* For each keyed field */
- if (myField->keyed == 'K')
- {
- /* Initializing new keyisn space */
- for (i=0; i< NUM_ISNS; i++)
- newisns[i] = 0;
- /* Store new block */
- /*
- printf("***Adding isn Table element for key %s***\n",myField->abbrev);
- */
- [myField->key_isns addElement:(int *)newisns];
- }
- }
- free(isns);
- free(newisns);
- return self;
- }
-
- int
- get_reclen(descript)
- char descript[];
- {
- int i, j, k, fldlen;
- char fld_name[3];
-
- k = 0;
- i = 0;
-
- while(i < strlen(descript)) {
- j = get2(&descript[i],&fld_name,&fldlen);
- i = i + j;
- /* need room to store length */
- k = k + fldlen+1;
- }
- /* room for isn, record len, and final byte */
- return(k+ISNRECSIZE+ISNRECSIZE+1);
- }
-
- int
- get2(descript,fld,fld_len)
- char fld[], descript[];
- int *fld_len;
- {
- int m;
- long k;
-
- m = 0;
- while (descript[m] != '\0') {
- fld[0] = descript[m++];
- fld[1] = descript[m++];
- fld[2] = '\0';
- m++; /* skip past comma */
- switch (descript[m]) {
- case 'I':
- m++;
- *fld_len = sizeof(m);
- return(++m);
- case 'L':
- m++;
- *fld_len = sizeof(k);
- return(++m);
- default:
- *fld_len = (descript[m++] & 0x0f);
- if ( descript[m] == '\0' ) break;
- while (descript[m] != ',')
- *fld_len = *fld_len * 10 + (descript[m++] & 0x0f);
- return(++m);
- }
- }
- return(m);
- }
-
- - prtRecAtIsn:(int)isn
- {
- int i, ii, j, k, blkno;
- int nfields = [self numberFlds];
- long ll;
- char *mybuffer, prt_str[BUFFSIZE];
- FIELD *myField;
-
- i = 0;
- if ((blkno = [self getBlockwithIsn:isn]) == -1) return self;
- mybuffer = (char *)[self getBlk:blkno];
- j = locisn(isn,&mybuffer[0]);
- for (k = 0; k < nfields; k++)
- {
- myField = [myDFD elementAt:k];
- switch (myField->kind) {
- case 'I':
- ii = 0;
- gn_I_fld(&ii,k,&mybuffer[j]);
- printf("%s : %d\n",myField->name,ii);
- break;
- case 'L':
- ll = 0;
- gn_L_fld(&ll,k,&mybuffer[j]);
- printf("%s : %ld\n",myField->name,ll);
- break;
- case 'A':
- strcpy(prt_str,"");
- gn_A_fld(prt_str,k,
- myField->display_len+1,&mybuffer[j]);
- printf("%s : %s\n",myField->name,prt_str);
- break;
- }
-
- }
- return self;
- }
-
- - status
- {
- int i,k,isns_used;
- FIELD *myField;
-
- isns_used = 0;
-
- printf("------- Status Report for Data Base ---- %s ---\n",
- myInfo->dBaseName);
- for (i = 0;i<myInfo->last_isn;i++)
- if ( [self getBlockwithIsn:i] != -1) isns_used++;
-
- printf(" Created using version %d of software\n", myInfo->version);
- printf(" %d ISNs used out of a maximum of %d - next isn = %d\n",
- isns_used,myInfo->max_isns,myInfo->last_isn);
- printf(" %d Buffers allocated, size = %d\n",
- myInfo->nbuf, BUFFSIZE);
- printf(" %d isns stored per block\n",NUM_ISNS);
- printf(" Update space : %d percent\n",(int)((1.-myInfo->data_frac)*100));
- printf(" Last dump date and time were : %d %d\n"
- ,myInfo->dump_date,myInfo->dump_time);
- printf(" There are %d fields defined for the database\n"
- ,[self numberFlds]);
- printf(" There are %d keyed fields \n",
- [self numKeyedFlds]);
- printf("------- FILE USAGE--------------------------\n");
- printf(" FILE ");
- for(i=0;i<8;i++) printf("<%-5d",(i+1)*BUFFSIZE/8-1);
- printf(" TOTAL\n");
- printf("------------------------------------------------------------\n");
- [self prt_one_status];
- printf("------------------------------------------------------------\n");
- k = 0;
- for (i=0;i<[self numberFlds];i++)
- {
- myField = [self getFldDesc:i];
- if (myField->keyed == 'K')
- k = k + [myField->hash count] * sizeof(KEY_VALUE);
- }
-
- printf("Key value storage = %d bytes\n",
- k);
- printf("Isn storage = %d bytes\n",BUFFSIZE*[isnTable count]);
- printf("Key list storage = %d bytes\n",BUFFSIZE*[isnTable count]
- * [self numKeyedFlds]);
- printf("\n");
- return self;
- }
-
- - prt_one_status
- {
- int charno,i,j,k, comp_fact;
- int block, old_block, use[8], total_avail;
- char *mybuffer;
- file_data *file_info = &(myInfo->data_file);
-
- comp_fact = BUFFSIZE/256;
- /* amount of space represented by "1" in
- in block alloc table */
-
- old_block = -1;
- for (i = 0; i<8; i++) use[i] = 0;
- total_avail = file_info->blks;
-
- for (k =0;k<file_info->blks;k++) {
- charno = k;
- block = charno/BUFFSIZE;
- charno = mod(charno,BUFFSIZE);
- if ( block != old_block )
- {
- mybuffer = [spaceTable elementAt:block];
- old_block = block;
- }
- i = (mybuffer[charno] & 0XFF);
- i = i * comp_fact;
- /* space is divided by comp_fact in space avail list*/
- j =i /(BUFFSIZE/8);
- use[j] = use[j] + 1;
- }
- printf("%10.10s: ",myInfo->dBaseName);
- for (i=0;i<8;i++)
- printf("%6d",use[i]);
- printf("%6d\n",total_avail);
- return self;
- }
-
- - prtStructure
- {
- int i, j= [self numberFlds];
- FIELD *myField;
-
- printf("--------- Record Structure -----%s-------\n",myInfo->dBaseName);
- for(i=0;i<j;i++) {
- myField = [myDFD elementAt:i];
- printf("%2d>%s:%c:%d \t%-16s %c %s\n",i,myField->abbrev,
- myField->kind,myField->display_len,
- myField->name,myField->keyed,
- myField->edit_mask);
- }
- printf("---------------------------------------------- \n");
-
- return self;
- }
-
- int
- gn_I_fld(dptr,j,recordptr)
- int j;
- char dptr[],recordptr[];
- {
- int i,k,l,field_len;
-
- if ((i = loc_fld(j,&recordptr[0])) == -1)
- field_len = 1;
- else field_len = recordptr[i];
- if ((field_len-1) == 0) {
- for (l = 0; l < sizeof(k); l++)
- dptr[l] = '\0';
- return(0);
- }
- for (l = 0; l < sizeof(k); l++)
- dptr[l] = recordptr[l+i+1];
- return(1);
- }
-
- int
- gn_L_fld(dptr,j,recordptr)
- int j;
- char dptr[],recordptr[];
- {
- int i,l,field_len;
- long k;
-
- if ((i = loc_fld(j,&recordptr[0])) == -1)
- field_len = 1;
- else field_len = recordptr[i];
- if ((field_len-1) == 0) {
- for (l = 0; l < sizeof(k); l++)
- dptr[l] = '\0';
- return(0);
- }
- for (l = 0; l < sizeof(k); l++)
- dptr[l] = recordptr[l+i+1];
- return(1);
- }
-
- int
- gn_A_fld(dptr,j,lenreq,recordptr)
- int j,lenreq;
- char dptr[],recordptr[];
- {
- int i,field_len,k;
-
- if ((i = loc_fld(j,&recordptr[0])) == -1)
- field_len = 1;
- else field_len = recordptr[i] - 1;
- if ((field_len - 1) == 0) {
- strcpy(&dptr[0],"");
- return(0);
- }
- field_len= min(field_len,lenreq-1);
- /* be sure to leave room for terminating null */
- for (k=0; k<field_len; k++) {
- dptr[k] = recordptr[i+k+1];
- dptr[k+1] = '\0';
- /* append null at end since not stored in record */
- }
- return(1);
- }
-
- - dumpSpace
- {
- int i,j, k;
- char *mySpace;
-
- j = [spaceTable count];
- printf("Dumping %d blocks of space table info\n",j);
- for (i=0; i<j; i++)
- {
- printf("Block %d ---------------\n",i);
- mySpace = (char *)[spaceTable elementAt:i];
- for (k=0; k<BUFFSIZE; k++)
- {
- if (mod (k,16) == 0)
- printf("\n");
- printf("%02x",(mySpace[k] & 0xff));
- }
- printf("\n");
- }
- return self;
- }
-
- - dumpIsns
- {
- int i,j, k;
- int *myIsns;
-
- j = [isnTable count];
- printf("Dumping %d blocks of isn table info\n",j);
- for (i=0; i<j; i++)
- {
- printf("Block %d ---------------\n",i);
- myIsns = (int *)[isnTable elementAt:i];
- for (k=0; k<NUM_ISNS; k++)
- {
- if (mod (k,10) == 0)
- printf("\n");
- printf("%5d ",*myIsns++);
- }
- printf("\n");
- }
- return self;
- }
-
- - dumpKeys
- {
- return self;
- }
-
- int
- loc_fld(i,buffer)
- int i;
- char buffer[];
- {
- int field_ptr,k,field_len;
-
- /* step past reclen and isn# */
- field_ptr = ISNRECSIZE + ISNRECSIZE;
- if (i == 0) return(field_ptr);
- for (k=1; k <= i; k++) {
- field_len = buffer[field_ptr];
- if (field_len == '\0') return(-1);
- field_ptr = field_ptr + field_len;
- }
- if (buffer[field_ptr] == '\0') return(-1);
- else return(field_ptr);
- }
-
- - dumpIsns:(int *)isns toFile:(char *)dump_file_name
- {
- char *mybuffer;
- char a_out[256];
- int i,j,k,l,len, i_out, l_out, isn;
- FILE *dump_file;
- char str[3] = "|";
- FIELD *myField;
-
- dump_file = (FILE *)fopen(dump_file_name,"w");
-
- myInfo->dump_date = 0101;
- myInfo->dump_time = 151500;
-
- fprintf(dump_file,"%s%d%s%d\n",str,myInfo->dump_date,str,
- myInfo->dump_time,str);
-
- /*
- if (myInfo->journal_flag)
- journal(dbname,tst_info->last_isn,DU,
- &buffer[0],tst_info->data_file.ptr);
- */
- for (i=0;i<isns[0];i++)
- {
- isn = isns[i+1];
- if ((j = [self getBlockwithIsn:isn]) != -1 ) {
- mybuffer = (char *)[self getBlk:j];
- j = locisn(isn,&mybuffer[0]);
- fprintf(dump_file,"%s\n%d",str,isn);
- for (k = 0; k < [self numberFlds]; k++)
- {
- myField = [self getFldDesc:k];
- switch (myField->kind) {
- case 'I':
- i_out = 0;
- if ((l = gn_I_fld(&i_out,k,&mybuffer[j])) != 0)
- fprintf(dump_file,"%s%d",str,i_out);
- else
- fprintf(dump_file,"%s",str);
- break;
- case 'L':
- l_out = 0;
- if ((l = gn_L_fld(&l_out,k,&mybuffer[j])) != 0)
- fprintf(dump_file,"%s%ld",str,l_out);
- else
- fprintf(dump_file,"%s",str);
- break;
- case 'A':
- len = 256;
- strcpy(a_out,"");
- if ((l = gn_A_fld(a_out,k,len,&mybuffer[j])) != 0)
- fprintf(dump_file,"%s%s",str,a_out);
- else
- fprintf(dump_file,"%s",str);
- break;
- }
- }
- }
- }
- fprintf(dump_file,"\n");
- fclose(dump_file);
-
- /* Write completion of dump at date time to journal if required */
- return self;
- }
-
-
- - loadDBfromFile:(char *)file_name
- {
- FILE *fptr;
- char *desc_str = (char *)calloc(BUFFSIZE,sizeof(char));
- char *data_str = (char *)calloc(BUFFSIZE,sizeof(char));
- char delim;
-
- if(!(fptr = fopen(file_name,"r")))
- {
- printf("Error: loadDBFromFile...file %s not found\n",file_name);
- exit(0);
- }
-
- fgets(desc_str,128,fptr); /* get dump dates */
- fgets(data_str,128,fptr); /* get next line */
- delim = desc_str[0];
-
- while([self loadDB:fptr:desc_str:data_str:delim])
- {
- [self addData:data_str:desc_str];
- }
- free(desc_str);
- free(data_str);
- return self;
- }
-
- - (int)loadDB:(FILE *)fptr:(char *)desc_str:(char *)data_str:(char)delim
- {
- int i, ii, k;
- long ll;
- char *mybuffer, prt_str[1024], tmp_str[1024],
- *tmp, *hold_desc, *hold_data;
- FIELD *myField;
-
- hold_desc = desc_str;
- hold_data = data_str;
- strcpy(desc_str,"");
- strcpy(data_str,"");
-
- if(fgets(prt_str,1023,fptr) == NULL) return(FALSE);
- mybuffer = prt_str;
- while(*++mybuffer != delim);
- k = 0;
- while(*mybuffer != '\0' && *mybuffer != '\n') {
- if(*++mybuffer == delim || *mybuffer == '\n') {
- if(++k > [self numberFlds]) break;
- continue;
- }
- myField = [self getFldDesc:k];
- *desc_str++ = myField->abbrev[0];
- *desc_str++ = myField->abbrev[1];
- *desc_str++ = ',';
- tmp = tmp_str;
- strcpy(tmp_str,"");
- while(*mybuffer != delim && *mybuffer != '\0')
- *tmp++ = *mybuffer++;
- *tmp = '\0';
- mybuffer--;
- switch (myField->kind) {
- case 'I':
- *desc_str++ = 'I';
- *desc_str++ = ',';
- ii = atoi(tmp_str);
- memcpy(data_str,&ii,sizeof(ii));
- for(ii=0;ii<sizeof(ii);ii++)
- data_str++;
- break;
- case 'L':
- *desc_str++ = 'L';
- *desc_str++ = ',';
- ll = atol(tmp_str);
- memcpy(data_str,&ll,sizeof(ll));
- for(ii=0;ii<sizeof(ll);ii++)
- data_str++;
- break;
- case 'A':
- i = strlen(tmp_str) + 1;
- if ( (i/100) > 0) *desc_str++ = (i/100) + 48;
- if ((i-i/100)/10 > 0) *desc_str++ = mod(i,100)/10 + 48;
- *desc_str++ = mod(i,10) + 48;
- *desc_str++ = ',';
- memcpy(data_str,tmp_str,i);
- for(ii=0;ii<i;ii++)
- data_str++;
- break;
- }
- }
- *desc_str = '\0';
- *data_str = '\0';
- desc_str = hold_desc;
- data_str = hold_data;
- return(TRUE);
- }
-
- - (int *)andIsns
- {
- /* AND */
- int *last, *isns, *new;
-
- Isns = [self pushList:min(*Last,*Isns)];
- isns = Last;
- last = Hold;
- new = Isns;
- *new = 0;
- ++last; ++isns; ++new;
-
- while(1)
- if ( *last < *isns )
- last++;
- else if ( *last > *isns )
- isns++;
- else /* *last == *isns */
- {
- *new++ = *last++; isns++; (*Isns)++;
- if ( *(new-1) == LASTISN ) {
- if(*Isns > 0) (*Isns)--;
- else new[1] = LASTISN;
- return Isns;
- }
- }
- }
-
- - (int *)orIsns
- {
- /* OR */
- int *last, *isns, *new;
-
- Isns = [self pushList:*Last+*Isns];
- new = Isns;
- *new = 0;
- last = Hold;
- isns = Last;
- ++last; ++isns; ++new;
-
- while(1)
- if ( *last < *isns )
- {
- *new++ = *last++; (*Isns)++;
- }
- else if ( *last > *isns )
- {
- *new++ = *isns++; (*Isns)++;
- }
- else /* *last == *isns */
- {
- *new++ = *last++; isns++; (*Isns)++;
- if ( *(new-1) == LASTISN ) {
- (*Isns)--;
- return Isns;
- }
- }
- }
-
- - (int *)xorIsns
- {
- /* XOR */
- int *last, *isns, *new;
-
- Isns = [self pushList:*Last+*Isns];
- new = Isns;
- *new = 0;
- last = Hold;
- isns = Last;
- ++last; ++isns; ++new;
-
- while(1)
- if ( *last < *isns )
- {
- *new++ = *last++; (*Isns)++;
- }
- else if ( *last > *isns )
- {
- *new++ = *isns++; (*Isns)++;
- }
- else /* *last == *isns */
- {
- last++; isns++;
- if ( *(last-1) == LASTISN ) {
- if(*Isns > 0) *new = LASTISN;
- else new[1] = LASTISN;
- return Isns;
- }
- }
- }
-
- - (int *)notIsns
- {
- /* set Last = all and xor */
- [self getIsnListforField:"*" value:"ALL"];
- return [self xorIsns];
- }
-
- - (int *)getIsnList
- {
- return Isns;
- }
-
- - (int *)getLastList
- {
- return Last;
- }
-
- - (int)getListCount
- {
- return *Isns;
- }
-
- int max(i,j)
- int i,j;
- {
- if ( i >= j) return (i);
- else return(j);
- }
-
- int mod(m,n)
- int m,n;
- {
-
- if (n == 0) {
- printf("Error: mod...modulus of 0 undefined\n");
- exit(0);
- }
-
- return( m - (m/n)*n );
-
- }
-
- int min(i,j)
- int i,j;
- {
- if ( i <= j ) return(i);
- else return(j);
- }
- @end
-